package com.xiuyi.pixsynergybackend.service.picture;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiuyi.pixsynergybackend.controller.file.dto.UploadPictureResultDTO;
import com.xiuyi.pixsynergybackend.controller.picture.vo.PictureQueryReqVO;
import com.xiuyi.pixsynergybackend.controller.picture.vo.PictureUploadReqVO;
import com.xiuyi.pixsynergybackend.controller.picture.vo.PictureVO;
import com.xiuyi.pixsynergybackend.controller.user.vo.UserVO;
import com.xiuyi.pixsynergybackend.dal.dataobject.picture.PictureDO;
import com.xiuyi.pixsynergybackend.dal.dataobject.user.UserDO;
import com.xiuyi.pixsynergybackend.dal.mapper.picture.PictureMapper;
import com.xiuyi.pixsynergybackend.exception.ErrorCode;
import com.xiuyi.pixsynergybackend.exception.ThrowUtils;
import com.xiuyi.pixsynergybackend.manager.FileManager;
import com.xiuyi.pixsynergybackend.service.user.UserService;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author zyt
 * @description 针对表【picture(图片)】的数据库操作Service实现
 * @createDate 2025-05-15 16:01:09
 */
@Service
public class PictureServiceImpl extends ServiceImpl<PictureMapper, PictureDO>
        implements PictureService {

    @Resource
    private FileManager fileManager;

    @Resource
    private UserService userService;

    /**
     * 上传图片
     *
     * @param multipartFile
     * @param pictureUploadReqVO
     * @param loginUser
     * @return
     */
    @Override
    public PictureVO uploadPicture(MultipartFile multipartFile, PictureUploadReqVO pictureUploadReqVO, UserDO loginUser) {
        ThrowUtils.throwIf(loginUser == null, ErrorCode.NO_AUTH_ERROR);
        // 用于判断是否新增还是更新图片
        Long pictureId = null;
        if (pictureUploadReqVO != null) {
            pictureId = pictureUploadReqVO.getId();
        }

        // 若是更新，判断图片是否存在
        if (pictureId != null) {
            boolean exists = this.lambdaQuery().eq(PictureDO::getId, pictureId).exists();
            ThrowUtils.throwIf(!exists, ErrorCode.NOT_FOUND_ERROR, "图片不存在");
        }

        // 按照用户ID 划分目录
        String uploadPathPrefix = String.format("public/%s", loginUser.getId());

        // 上传图片 获取图片信息
        UploadPictureResultDTO uploadPictureResultDTO = fileManager.uploadPicture(multipartFile, uploadPathPrefix);

        // 构造要入库的图片信息
        PictureDO pictureDO = new PictureDO();
        pictureDO.setUrl(uploadPictureResultDTO.getUrl());
        pictureDO.setName(uploadPictureResultDTO.getPicName());
        pictureDO.setPicSize(uploadPictureResultDTO.getPicSize());
        pictureDO.setPicWidth(uploadPictureResultDTO.getPicWidth());
        pictureDO.setPicHeight(uploadPictureResultDTO.getPicHeight());
        pictureDO.setPicScale(uploadPictureResultDTO.getPicScale());
        pictureDO.setPicFormat(uploadPictureResultDTO.getPicFormat());
        pictureDO.setUserId(loginUser.getId());

        // 如果 pictureID 不为空，表示更新，否则是新增
        if (pictureId != null) {
            // 若是更新，需要补充id和编辑时间
            pictureDO.setId(pictureId);
            pictureDO.setEditTime(new Date());
        }
        boolean result = this.saveOrUpdate(pictureDO);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR, "图片上传失败");
        return PictureVO.doToVO(pictureDO);
    }

    /**
     * 获取查询条件
     *
     * @param pictureQueryReqVO
     * @return
     */
    @Override
    public QueryWrapper<PictureDO> getQueryWrapper(PictureQueryReqVO pictureQueryReqVO) {
        QueryWrapper<PictureDO> queryWrapper = new QueryWrapper<>();
        if (pictureQueryReqVO == null) {
            return queryWrapper;
        }
        // 从对象中取值
        Long id = pictureQueryReqVO.getId();
        String name = pictureQueryReqVO.getName();
        String introduction = pictureQueryReqVO.getIntroduction();
        String category = pictureQueryReqVO.getCategory();
        List<String> tags = pictureQueryReqVO.getTags();
        Long picSize = pictureQueryReqVO.getPicSize();
        Integer picWidth = pictureQueryReqVO.getPicWidth();
        Integer picHeight = pictureQueryReqVO.getPicHeight();
        Double picScale = pictureQueryReqVO.getPicScale();
        String picFormat = pictureQueryReqVO.getPicFormat();
        String searchText = pictureQueryReqVO.getSearchText();
        Long userId = pictureQueryReqVO.getUserId();
        String sortField = pictureQueryReqVO.getSortField();
        String sortOrder = pictureQueryReqVO.getSortOrder();
        // 从多字段搜索
        if (StrUtil.isNotBlank(searchText)) {
            // 需要拼接查询条件
            queryWrapper.and(qw -> qw.like("name", searchText)
                    .or()
                    .like("introduction", searchText));
        }
        queryWrapper.eq(ObjUtil.isNotEmpty(id), "id", id);
        queryWrapper.eq(ObjUtil.isNotEmpty(userId), "userId", userId);
        queryWrapper.like(StrUtil.isNotBlank(name), "name", name);
        queryWrapper.like(StrUtil.isNotBlank(introduction), "introduction", introduction);
        queryWrapper.like(StrUtil.isNotBlank(picFormat), "picFormat", picFormat);
        queryWrapper.eq(StrUtil.isNotBlank(category), "category", category);
        queryWrapper.eq(ObjUtil.isNotEmpty(picWidth), "picWidth", picWidth);
        queryWrapper.eq(ObjUtil.isNotEmpty(picHeight), "picHeight", picHeight);
        queryWrapper.eq(ObjUtil.isNotEmpty(picScale), "picScale", picScale);
        queryWrapper.eq(ObjUtil.isNotEmpty(picSize), "picSize", picSize);
        // JSON 数组查询
        if (CollUtil.isNotEmpty(tags)) {
            for (String tag : tags) {
                queryWrapper.like("tags", "\"" + tag + "\"");
            }
        }
        // 排序
        queryWrapper.orderBy(StrUtil.isNotEmpty(sortField), sortOrder.equals("ascend"), sortField);
        return queryWrapper;
    }

    /**
     * 获取单个图片
     *
     * @param pictureDO
     * @param request
     * @return
     */
    @Override
    public PictureVO getPictureVO(PictureDO pictureDO, HttpServletRequest request) {
        // 对象封装类
        PictureVO pictureVO = PictureVO.doToVO(pictureDO);
        // 关联查询用户信息
        Long userId = pictureVO.getUserId();
        if (userId != null && userId > 0) {
            UserDO userDO = userService.getById(userId);
            UserVO userVO = userService.getUserVO(userDO);
            pictureVO.setUser(userVO);
        }
        return pictureVO;
    }

    /**
     * 分页获取图片
     *
     * @param pictureDOPage
     * @param request
     * @return
     */
    @Override
    public Page<PictureVO> getPictureVOPage(Page<PictureDO> pictureDOPage, HttpServletRequest request) {
        // 从入参分页对象中获取DO数据列表
        List<PictureDO> pictureDOList = pictureDOPage.getRecords();

        // 创建新的VO分页对象，继承原始分页参数（页码/页大小/总数）
        Page<PictureVO> pictureVOPage = new Page<>(pictureDOPage.getCurrent(), pictureDOPage.getSize(), pictureDOPage.getTotal());

        // 空数据快速返回
        if (CollUtil.isEmpty(pictureDOList)) {
            return pictureVOPage;
        }

        // DO列表转VO列表（基础属性拷贝）
        List<PictureVO> pictureVOList = pictureDOList.stream()
                .map(PictureVO::doToVO)  // 使用静态方法转换单个对象
                .collect(Collectors.toList());

        // 1.关联查询用户信息-------------------------------------------------------
        // 提取所有图片关联的用户ID
        Set<Long> userIdSet = pictureDOList.stream()
                .map(PictureDO::getUserId)
                .collect(Collectors.toSet());

        // 批量查询用户数据并构建ID->用户对象的映射（注意：假设userService.listByIds返回唯一用户）
        Map<Long, List<UserDO>> userIdUserDOListMap = userService.listByIds(userIdSet)
                .stream()
                .collect(Collectors.groupingBy(UserDO::getId)); // 按用户ID分组

        // 2.填充关联信息----------------------------------------------------------
        pictureVOList.forEach(pictureVO -> {
            Long userId = pictureVO.getUserId();
            UserDO userDO = null;

            // 从映射表中获取用户数据（取分组后的第一个元素）
            if (userIdUserDOListMap.containsKey(userId)) {
                userDO = userIdUserDOListMap.get(userId).get(0); // 注意：这里假设ID唯一
            }

            // 将UserDO转换为UserVO并设置到图片VO中
            pictureVO.setUser(userService.getUserVO(userDO));
        });

        // 将处理后的VO列表设置到分页对象
        pictureVOPage.setRecords(pictureVOList);
        return pictureVOPage;
    }

    /**
     * 校验图片数据
     *
     * @param pictureDO
     */
    @Override
    public void validPicture(PictureDO pictureDO) {
        ThrowUtils.throwIf(pictureDO == null, ErrorCode.PARAMS_ERROR);
        // 从对象中取值
        Long id = pictureDO.getId();
        String url = pictureDO.getUrl();
        String introduction = pictureDO.getIntroduction();
        // 修改数据是，id 不能为空
        ThrowUtils.throwIf(ObjUtil.isNull(id), ErrorCode.PARAMS_ERROR, "id 不能为空");
        if (StrUtil.isNotBlank(url)) {
            ThrowUtils.throwIf(url.length() > 1024, ErrorCode.PARAMS_ERROR, "url 过长");
        }
        if (StrUtil.isNotBlank(introduction)) {
            ThrowUtils.throwIf(introduction.length() > 800, ErrorCode.PARAMS_ERROR, "简介过长");
        }
    }
}




